package com.jiangyao.common;


import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.PageInfo;
import com.jiangyao.common.handler.SpringContextHolder;
import com.jiangyao.model.vo.ListPageVO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.dozer.DozerBeanMapper;
import org.dozer.Mapper;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpStatus;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * 返回参数
 *
 * @author yangyongchuan
 * @since 2020-08-07
 */
@Data
@ApiModel("返回参数")
public final class ApiResult<T> implements Serializable {

	private static final long serialVersionUID = 2861839152462977463L;
	/**
	 * 响应code:200=ok,500=error,403=Forbidden、Unauthorized
	 */
	@ApiModelProperty(value = "响应code")
	private Integer code;
	/**
	 * 错误信息
	 */
	@ApiModelProperty(value = "错误信息")
	private String msg;
	/**
	 * 返回数据
	 */
	@ApiModelProperty(value = "返回数据")
	private T data;

	public ApiResult() {
		this.code = HttpStatus.OK.value();
		this.msg = HttpStatus.OK.getReasonPhrase();
	}

	public ApiResult(Integer code, String msg) {
		this.code = code;
		this.msg = msg;
	}

	public ApiResult(Integer code, String msg, T data) {
		this.code = code;
		this.msg = msg;
		this.data = data;
	}

	public ApiResult(HttpStatus httpStatus) {
		this.code = httpStatus.value();
		this.msg = httpStatus.getReasonPhrase();
	}

	public ApiResult(T data) {
		this.code = HttpStatus.OK.value();
		this.msg = HttpStatus.OK.getReasonPhrase();
		this.data = data;
	}

	public static ApiResult success(Object data) {
		return new ApiResult(HttpStatus.OK.value(), HttpStatus.OK.getReasonPhrase(), data);
	}

	public static ApiResult success(Object data, Class destCls) {
		if (data == null) {
			return new ApiResult();
		}
		ApplicationContext applicationContext = SpringContextHolder.getApplicationContext();
		Mapper mapper = applicationContext.getBean(DozerBeanMapper.class);
		Object destObject = mapper.map(data, destCls);
		return new ApiResult(HttpStatus.OK.value(), HttpStatus.OK.getReasonPhrase(), destObject);
	}

	public static ApiResult success(List list) {
		return new ApiResult(HttpStatus.OK.value(), HttpStatus.OK.getReasonPhrase(), list);
	}

	public static ApiResult success(List list, Class destCls) {
		if (list == null) {
			return new ApiResult();
		}
		ApplicationContext applicationContext = SpringContextHolder.getApplicationContext();
		Mapper mapper = applicationContext.getBean(DozerBeanMapper.class);
		List destList = new ArrayList(list.size());
		for (Iterator iterator = list.iterator(); iterator.hasNext(); ) {
			Object sourceObject = iterator.next();
			Object destinationObject = mapper.map(sourceObject, destCls);
			destList.add(destinationObject);
		}
		return new ApiResult(HttpStatus.OK.value(), HttpStatus.OK.getReasonPhrase(), destList);
	}

	public static ApiResult success(Page page) {
		if (page == null) {
			return new ApiResult();
		}
		ListPageVO listPageVO = new ListPageVO();
		ListPageVO.Page listPageVOPage = new ListPageVO.Page();
		listPageVOPage.setTotal(page.getTotal());
		listPageVOPage.setPages(page.getPages());
		listPageVOPage.setPageNo(page.getCurrent());
		listPageVOPage.setPageSize(page.getSize());
		listPageVO.setPage(listPageVOPage);
		listPageVO.setList(page.getRecords());
		return new ApiResult(HttpStatus.OK.value(), HttpStatus.OK.getReasonPhrase(), listPageVO);
	}

	public static ApiResult success(Page page, Class destCls) {
		if (page == null) {
			return new ApiResult();
		}
		ListPageVO listPageVO = new ListPageVO();
		ListPageVO.Page listPageVOPage = new ListPageVO.Page();
		listPageVOPage.setTotal(page.getTotal());
		listPageVOPage.setPages(page.getPages());
		listPageVOPage.setPageNo(page.getCurrent());
		listPageVOPage.setPageSize(page.getSize());
		listPageVO.setPage(listPageVOPage);

		ApplicationContext applicationContext = SpringContextHolder.getApplicationContext();
		Mapper mapper = applicationContext.getBean(DozerBeanMapper.class);
		List destList = new ArrayList(page.getRecords().size());
		for (Iterator iterator = page.getRecords().iterator(); iterator.hasNext(); ) {
			Object sourceObject = iterator.next();
			Object destinationObject = mapper.map(sourceObject, destCls);
			destList.add(destinationObject);
		}
		listPageVO.setList(destList);
		return new ApiResult(HttpStatus.OK.value(), HttpStatus.OK.getReasonPhrase(), listPageVO);
	}


	public static ApiResult success(PageInfo pageInfo) {
		if (pageInfo == null) {
			return new ApiResult();
		}
		ListPageVO listPageVO = new ListPageVO();
		ListPageVO.Page listPageVOPage = new ListPageVO.Page();
		listPageVOPage.setTotal(pageInfo.getTotal());
		listPageVOPage.setPages((long) pageInfo.getPages());
		listPageVOPage.setPageNo((long) pageInfo.getPageNum());
		listPageVOPage.setPageSize((long) pageInfo.getPageSize());
		listPageVO.setPage(listPageVOPage);
		listPageVO.setList(pageInfo.getList());
		return new ApiResult(HttpStatus.OK.value(), HttpStatus.OK.getReasonPhrase(), listPageVO);
	}

	public static ApiResult success(PageInfo pageInfo, Class destCls) {
		if (pageInfo == null) {
			return new ApiResult();
		}
		ListPageVO listPageVO = new ListPageVO();
		ListPageVO.Page listPageVOPage = new ListPageVO.Page();
		listPageVOPage.setTotal(pageInfo.getTotal());
		listPageVOPage.setPages((long) pageInfo.getPages());
		listPageVOPage.setPageNo((long) pageInfo.getPageNum());
		listPageVOPage.setPageSize((long) pageInfo.getPageSize());
		listPageVO.setPage(listPageVOPage);

		ApplicationContext applicationContext = SpringContextHolder.getApplicationContext();
		Mapper mapper = applicationContext.getBean(DozerBeanMapper.class);
		List destList = new ArrayList(pageInfo.getList().size());
		for (Iterator iterator = pageInfo.getList().iterator(); iterator.hasNext(); ) {
			Object sourceObject = iterator.next();
			Object destinationObject = mapper.map(sourceObject, destCls);
			destList.add(destinationObject);
		}
		listPageVO.setList(destList);
		return new ApiResult(HttpStatus.OK.value(), HttpStatus.OK.getReasonPhrase(), listPageVO);
	}


	public static ApiResult success(String msg) {
		return new ApiResult(HttpStatus.OK.value(), msg, null);
	}

	public static ApiResult error(HttpStatus httpStatus, String msg) {
		return new ApiResult(httpStatus.value(), msg, null);
	}

	public static ApiResult error(Integer code, String msg) {
		return new ApiResult(code, msg, null);
	}

	public static ApiResult error() {
		return new ApiResult(HttpStatus.INTERNAL_SERVER_ERROR.value(), HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase(), null);
	}

	public static ApiResult error(String msg) {
		return new ApiResult(HttpStatus.INTERNAL_SERVER_ERROR.value(), msg, null);
	}

}
